﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Agile.Engine.Data;
using Agile.Engine.Utils;
using System.Data;

namespace Fis.Web.Rules.Book
{
    public class AccountRule : DynamicRule
    {

        string TableName = "TACCOUNT";

        void AddNew(System.Data.DataTable data)
        {
            var valid = Model.QueryTable(TableName,
                string.Format("(FCODE='{0}' OR FNAME='{1}') AND FPARENT = '{2}'"
                , data.Rows[0]["FCODE"], data.Rows[0]["FNAME"], data.Rows[0]["FPARENT"]));
            if (valid.Rows.Count > 0)
            {
                Status = -1;
                Message = "编码或名称已存在";
                return;
            }

            var book = Model.QueryTable("TBOOK");
            if (!ValidAccountLevel(book.Rows[0]["FACCSTRUCT"].ToString(), data.Rows[0]["FCODE"].ToString()))
            {
                Status = -1;
                return;
            }

            var count = Model.Count(TableName, "FCODE", string.Format("FPARENT='{0}'", data.Rows[0]["FPARENT"]));

            data.Rows[0]["SID"] = Guid.NewGuid().ToString();
            data.Rows[0]["SINDEXDATE"] = DateTime.Now;
            data.Rows[0]["SBOOKID"] = BookID;
            data.AcceptChanges();
            data.Rows[0].SetAdded();
            data.TableName = TableName;
            Model.UpdateTable(data);

            //新建第一个子级的时候需要刷新上级业务数据到当前科目
            if (count <= 0)
            {
                var xml = Agile.Engine.ObjectContext.GetResource("BookResource");
                var bill = xml.Format("newAccountRefreashBill", data.Rows[0]["SID"], data.Rows[0]["FPARENT"]);
                //var rest = xml.Format("newAccountRefreashBill", data.Rows[0]["SID"], data.Rows[0]["FPARENT"]);
                Model.ExecuteNonQuery(bill);
                //Model.ExecuteNonQuery(rest);

                var rest = Model.QueryTable("TREST", string.Format("FACCCODE='{0}'", data.Rows[0]["FPARENT"]));

                foreach (var d in rest.AsEnumerable())
                {
                    d["SID"] = Guid.NewGuid().ToString();
                    d["FACCCODE"] = data.Rows[0]["SID"];
                    d["SINDEXDATE"] = DateTime.Now;
                    d.AcceptChanges();
                    d.SetAdded();
                }

                Model.UpdateTable(rest);

                Result["ISFIRSTCHILD"] = 1;
                if (rest.Rows.Count > 0)
                    Result["TREST"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(rest);
            }
        }

        void Modify(System.Data.DataTable data)
        {
            var valid = Model.QueryTable(TableName,
                string.Format("(FCODE='{0}' OR FNAME='{1}') AND FPARENT = '{2}'"
                , data.Rows[0]["FCODE"], data.Rows[0]["FNAME"], data.Rows[0]["FPARENT"]));
            if (valid.Rows.Count > 0)
            {
                Status = -1;
                Message = "编码或名称已存在";
                return;
            }

            var book = Model.QueryTable("TBOOK");
            if (!ValidAccountLevel(book.Rows[0]["FACCSTRUCT"].ToString(), data.Rows[0]["FCODE"].ToString()))
            {
                Status = -1;
                return;
            }

            data.Rows[0]["SINDEXDATE"] = DateTime.Now;
            data.AcceptChanges();
            data.Rows[0].SetModified();
            data.TableName = TableName;
            Model.UpdateTable(data);
        }

        void Delete(string sid)
        {
            var count = Model.ExecuteScalar(0, "SELECT COUNT(*) FROM TBILLDETAIL WHERE FACCOUNTCODE='" + sid + "'");
            if (count > 0)
            {
                Status = -1;
                Message = "会计科目已被使用，不能删除";
                return;
            }

            Model.Delete(TableName, "SID='" + sid + "'");
            CommonRule common = new CommonRule();
            common.UpdateDeleteInfo(Model.DataContext, TableName, sid, BookID);
        }

        bool ValidAccountLevel(string level, string code)
        {
            var accData = Model.QueryTable(TableName);
            var l = level.Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries);

            var len = 0;
            var parent = string.Empty;
            for (var i = 0; i < l.Length; i++)
            {
                len += int.Parse(l[i]);
                if (len > code.Length)
                {
                    Message = string.Format("科目编码结构错误，请参照{0}", level);
                    return false;
                }
                var c = code.Substring(0, len);

                //一级科目
                if (code.Length == len)
                    break;

                if (i != l.Length - 1)
                {
                    var acc = accData.Select(string.Format("FCODE='{0}'", c));
                    if (acc.Length > 0)
                    {
                        parent = acc[0]["SID"].ToString();
                    }
                    else
                    {
                        Message = string.Format("上级科目{0}不存在", c);
                        return false;
                    }
                }
                else
                {
                    Message = string.Format("科目编码结构错误，请参照{0}", level);
                    return false;
                }
            }

            return true;
        }

        public override void ExecuteNonTrans()
        {
            var action = Paramater["Action"].ToString();
            System.Data.DataTable data = null;
            Status = 1;

            switch (action)
            {
                case "AddNew":
                    data = ZipUtils.UnZipDataTable(Paramater["viewData"].ToString());
                    AddNew(data);
                    break;
                case "Modify":
                    data = ZipUtils.UnZipDataTable(Paramater["viewData"].ToString());
                    Modify(data);
                    break;
                case "Delete":
                    Delete(Paramater["SID"].ToString());
                    break;
            }

            if (data != null)
                Result["viewData"] = ZipUtils.ZipDataTable(data);

        }
    }
}
